using System.Collections;
using UnityEngine;

namespace Yoozoo.Gameplay.City
{
    public class CityEditorBase : MonoBehaviour
    {
        [Header("游戏内城的格子大小匹配")]
        public Vector3 cityCellSize = new Vector3(0.015625f, 0.01f, 0.015625f);
        [Header("内城视觉旋转角")]
        public float gridViewAngleY = 45;
        
        [Header("区域格子数量")]
        public int width = 60;
        public int height = 60;
        
        [Header("内城相机")]
        public Camera cityCamera;
        [Header("内城根节点")]
        public Transform cityRoot;
        
        [Header("用于编辑格子的显示")]
        public MeshRenderer gridRenderer;
        [Header("用于射线检测")]
        public Collider collider;
        
        [Header("坐标预制体")]
        public GameObject coordinatePrefab;
        [Header("是否显示坐标")]
        public bool showCoordinate = false;
        [Header("显示坐标的左上位置")]
        public Vector2Int showCoordinateLT = Vector2Int.zero;
        [Header("显示坐标的右下位置")]
        public Vector2Int showCoordinateRB = Vector2Int.zero;
        
        // 根据点击位置得到内城格子索引
        protected Vector2Int GetGrid(Vector3 pos)
        {
            // 世界坐标转局部坐标
            Vector3 localPos = cityRoot.InverseTransformPoint(pos);

            localPos.x += 0.002f;
            localPos.z += 0.002f;
            localPos.y = 0;

            float negCityViewRad = -Mathf.PI * gridViewAngleY / 180.0f;
            float negCosCityViewRad = Mathf.Cos(negCityViewRad);
            float negSinCityViewRad = Mathf.Sin(negCityViewRad);
            
            // 局部坐标旋转到视觉坐标
            float ox = localPos.x;
            float oz = localPos.z;

            localPos.x = negCosCityViewRad * ox + negSinCityViewRad * oz;
            localPos.z = -negSinCityViewRad * ox + negCosCityViewRad * oz;

            // 计算格子索引
            Vector3 bottomLeft = new Vector3(-width * cityCellSize.x * 0.5f, 0, -height * cityCellSize.z * 0.5f);
            localPos -= bottomLeft;

            Vector2Int g = new Vector2Int();
            g.x = GetFloat2IntValue(localPos.x / cityCellSize.x);
            g.y = GetFloat2IntValue(localPos.z / cityCellSize.z);
            return g;
        }

        public Vector3 GetPos(Vector2Int grid)
        {
            Vector3 pos = Vector3.zero;

            pos.x = grid.x * cityCellSize.x;
            pos.z = grid.y * cityCellSize.z;

            Vector3 bottomLeft = new Vector3(-width * cityCellSize.x * 0.5f, 0, -height * cityCellSize.z * 0.5f);

            pos += bottomLeft;

            // 为啥要根据边长来决定是否居中，注掉先
            pos += new Vector3(
                /*width % 2 */ cityCellSize.x * 0.5f,
                0,
                /*height % 2 */ cityCellSize.z * 0.5f);


            float cityViewRad = Mathf.PI * gridViewAngleY / 180.0f;
            float cosCityViewRad = Mathf.Cos(cityViewRad);
            float sinCityViewRad = Mathf.Sin(cityViewRad);


            float ox = pos.x;
            float oz = pos.z;

            pos.x = cosCityViewRad * ox + sinCityViewRad * oz;
            pos.z = -sinCityViewRad * ox + cosCityViewRad * oz;

            return pos;
        }

        protected int GetFloat2IntValue(float v)
        {
            if (v < 0)
            {
                v -= 0.01f;
                return Mathf.CeilToInt(v);
            }

            v += 0.01f;
            return Mathf.FloorToInt(v);
        }

        protected int GetGridId(Vector2Int grid)
        {
            return grid.x * height + grid.y;
        }
        
        protected bool GetClickPos(Vector3 pos,out Vector3 hitPos)
        {
            Ray camRay = cityCamera.ScreenPointToRay(pos);
            RaycastHit hit;
            if (Physics.Raycast(camRay, out hit,10000,1<<LayerMask.NameToLayer("FogCollision")))
            {
                hitPos = hit.point;
                return true;
            }
            hitPos = Vector3.back;
            return false;
        }

        // 根据格子的长宽，为每个格子中心生成一个TextMeshPro，显示格子的坐标
        protected IEnumerator GenerateGridCoordinateText()
        {
            if (!showCoordinate)
            {
                yield break;
            }
            
            GameObject coordinateRoot = new GameObject("CoordinateRoot");
            coordinateRoot.transform.eulerAngles = new Vector3(0, 45, 0);
            for (int i = showCoordinateLT.x; i < showCoordinateRB.x; i++)
            {
                for (int j = showCoordinateLT.y; j < showCoordinateRB.y; j++)
                {
                    GameObject go = GameObject.Instantiate(coordinatePrefab, coordinateRoot.transform);
                    go.transform.localPosition = new Vector3((i - width * 0.5f) * cityCellSize.x+cityCellSize.x*0.5f, 0, (j - height * 0.5f) * cityCellSize.z + cityCellSize.z*0.5f);
                    var text = go.GetComponentInChildren<TMPro.TextMeshPro>();
                    text.text = $"{i},\n{j}";
                }

                yield return null;
            }
        }
        
    }
}
